/*********************************************************************
*
*   MODULE NAME:
*       vts_gm862_gps.cpp - GM862-GPS Module Interface
*
*   DESCRIPTION:
*       Interface for GM862-GPS module
*
* Copyright 2011 by KU onTime
*---------------------------------------------------------------------
* Version: 1.1 - Major changes to implement working module
* Version: 1.0 - Initial development
*
*********************************************************************/

/*--------------------------------------------------------------------
                            GENERAL INCLUDES
--------------------------------------------------------------------*/
#include "vts_gm862_gps.h"
#include <string.h>
#include <avr/pgmspace.h>

/*--------------------------------------------------------------------
                            LITERAL CONSTANTS
--------------------------------------------------------------------*/

#define MAX_BUF_SIZE  ( 100  )		/* Buffer Size					*/
#define TIMEOUT_VALUE ( 1000 )		/* Timeout Value in Millisec	*/

/*--------------------------------------------------------------------
                                 TYPES
--------------------------------------------------------------------*/

/*--------------------------------------------------------------------
                           PROJECT INCLUDES
--------------------------------------------------------------------*/

/*--------------------------------------------------------------------
                            MEMORY CONSTANTS
--------------------------------------------------------------------*/

/*--------------------------------------------------------------------
                               VARIABLES
--------------------------------------------------------------------*/

/*--------------------------------------------------------------------
                                 MACROS
--------------------------------------------------------------------*/

/*--------------------------------------------------------------------
                              PROCEDURES
--------------------------------------------------------------------*/

/*********************************************************************
*
*   PROCEDURE NAME:
*       vts_GM862_GPS - GM862-GPS Constructor
*
*   DESCRIPTION:
*       GM862-GPS Constructor
*
*********************************************************************/

vts_GM862_GPS::vts_GM862_GPS		/* GM862-GPS Constructor		*/
	( 
	HardwareSerial 		*serial_port_i, 	
									/* hardware serial port			*/
	uint16_t 			power_pin, 	/* hardware power pin			*/
	uint16_t 			power_sense_pin
									/* hardware power sense pin		*/
	)							
{
/*----------------------------------------------------------
Procedures
----------------------------------------------------------*/
state = vts_GM862_OFF;
serial_port = serial_port_i;
serial_port->begin( 19200 );
this->power_pin = power_pin;
this->power_sense_pin = power_sense_pin;
pinMode( power_pin, OUTPUT );
pinMode( power_sense_pin, INPUT );

}	/* vts_GM862_GPS() */


/*********************************************************************
*
*   PROCEDURE NAME:
*       Power_On - Power On GM862-GPS Module
*
*   DESCRIPTION:
*       Power On GM862-GPS Module
*
*********************************************************************/

void vts_GM862_GPS::Power_On		/* Power On GM862-GPS Module	*/
	( void )
{
/*----------------------------------------------------------
Procedures
----------------------------------------------------------*/
Serial.println( "GM862-GPS: Powering On" );

if( digitalRead( power_sense_pin ) == false )
	{
	digitalWrite( power_pin, HIGH );
	delay( 1000 );
	digitalWrite( power_pin, LOW );
	delay( 5000 );
	
	state = vts_GM862_ON;
	Serial.println( "GM862-GPS: On1" );
	}
else
	{
	state = vts_GM862_ON;
	Serial.println( "GM862-GPS: On" );
	}
	
}	/* Power_On() */


/*********************************************************************
*
*   PROCEDURE NAME:
*       Power_Off - Power Off GM862-GPS Module
*
*   DESCRIPTION:
*       Power Off GM862-GPS Module
*
*********************************************************************/

void vts_GM862_GPS::Power_Off		/* Power Off GM862-GPS Module	*/
	( void )
{
/*----------------------------------------------------------
Procedures
----------------------------------------------------------*/
Serial.println( "GM862-GPS: Powering Off" );
	
if( digitalRead( power_sense_pin ) == true )
	{
	digitalWrite( power_pin, HIGH );
	delay( 1000 );
	digitalWrite( power_pin, LOW );
	delay( 1000 );
	
	state = vts_GM862_OFF;
 
	Serial.println( "GM862-GPS: Off" );
	}
else
	{
	state = vts_GM862_OFF;
	Serial.println( "GM862-GPS: Off" );
	}
	
}	/* Power_Off() */


/*********************************************************************
*
*   PROCEDURE NAME:
*       Initialize - Initialize GM862-GPS Module	
*
*   DESCRIPTION:
*       Initialize GM862-GPS Module
*
*********************************************************************/

void vts_GM862_GPS::Initialize		/* Initialize GM862-GPS	Module	*/
	( void )
{
/*----------------------------------------------------------
Procedures
----------------------------------------------------------*/
Serial.println( "GM862-GPS: Initializing" );

if( state != vts_GM862_OFF )
	{
	send_command( "AT" );
	send_command( "AT+IPR = 19200" );
	send_command( "AT+CMEE = 2" );
	
	state = vts_GM862_INITIALIZED;
	
	Serial.println( "GM862-GPS: Initialized" );
	}
else
	{
	Serial.println( "GM862-GPS: Error - Currently in the OFF state" );
	}

}	/* Initialize() */


/*********************************************************************
*
*   PROCEDURE NAME:
*       Version_Info - Display Hardware Version	
*
*   DESCRIPTION:
*       Displays Hardware Version Information	
*
*********************************************************************/

void vts_GM862_GPS::Version_Info	/* Display Hardware Version		*/
	( void )
{
/*----------------------------------------------------------
Procedures
----------------------------------------------------------*/
Serial.println( "GM862-GPS: Version Information" );

if( state != vts_GM862_OFF )
	{
	send_command( "AT+GMM" );
	send_command( "AT+GMR" );
	send_command( "AT+CSQ" );
	}
else
	{
	Serial.println( "GM862-GPS: Error - Currently in the OFF state" );
	}

}	/* Version_Info() */


/*********************************************************************
*
*   PROCEDURE NAME:
*       send_command - Send Command To GM862-GPS
*
*   DESCRIPTION:
*       Send Command To GM862-GPS
*
*********************************************************************/

void vts_GM862_GPS::send_command	/* Send Command To GM862-GPS	*/
	( 
	const String command 			/* command to send				*/
    )
{
/*----------------------------------------------------------
Local Variables
----------------------------------------------------------*/		
String                                  module_buffer;
									/* return buffer				*/
byte					buffer_size;/* current buffer size			*/
long					timeout_tm;	/* timeout time to check		*/
char					tmp_char;	/* temporary character			*/
	
/*----------------------------------------------------------
Procedures
----------------------------------------------------------*/
buffer_size = 0;
module_buffer = "";

Serial.println( command );
serial_port->print( command );
serial_port->print( '\r' );

timeout_tm = millis() + TIMEOUT_VALUE;

while( ( millis() < timeout_tm 				)
	&& ( buffer_size < ( MAX_BUF_SIZE - 1 ) ) )
	{
	if( serial_port->available() )
		{
        tmp_char = serial_port->read();

		if( tmp_char != command[ buffer_size ] && tmp_char != '\n' )
			{
			module_buffer = module_buffer + tmp_char;
			}

		buffer_size++;
		
		timeout_tm = millis() + TIMEOUT_VALUE;
		}	
	}
	
if( buffer_size > 0 || module_buffer == ' ' )
	{
	Serial.println( module_buffer );
	}
else
	{
	Serial.println( "GM862-GPS: Error - Timeout Reached" );
	}
	
}	/* send_command() */


